package com.detect.core;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import org.springframework.stereotype.Service;

import com.detect.model.HashLevel;

@Service("hashCode")
public class HashCodeImpl implements HashCode {

    private HashLevel level;

    public HashCodeImpl() {
        level = HashLevel.DEFAULT_LEVEL;
    }

    public HashCodeImpl(HashLevel level) {
        this.level = level;
    }

    @Override
    public String getFileMD5(File file) {
        MessageDigest messagedigest = null;
        try {
            messagedigest = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        InputStream fis;
        try {
            fis = new FileInputStream(file);
            byte[] buffer = new byte[1024];
            int numRead = 0;
            int time = 0;
            // 控制计算大小
            while (!((numRead = fis.read(buffer)) <= 0 || (level == HashLevel.FULL ? false
                    : time > level.getVal()))) {
                messagedigest.update(buffer, 0, numRead);
                time++;
            }
            fis.close();
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        byte[] b = messagedigest.digest();
        String md5 = bufferToHex(b);
        return md5;
    }

    @Override
    public String getUrlMD5(String UrlName) {
        String name = "";
        try {
            URL url = new URL(UrlName);
            InputStream inputStream = new BufferedInputStream(url.openStream());
            byte[] bytes = new byte[1024];
            int len = 0;
            MessageDigest messagedigest = MessageDigest.getInstance("MD5");
            while ((len = inputStream.read(bytes)) > 0) {
                messagedigest.update(bytes, 0, len);
            }
            name = bufferToHex(messagedigest.digest());
            inputStream.close();
        } catch (MalformedURLException e) {
            // LogUtil.getLogger().warn(e);
        } catch (IOException e) {
            // LogUtil.getLogger().warn(e);
        } catch (NoSuchAlgorithmException e) {
            // LogUtil.getLogger().warn(e);
        }
        return name;
    }

    @Override
    public String getStringMD5(String str) {
        byte[] buffer = str.getBytes();
        MessageDigest messagedigest = null;
        try {
            messagedigest = MessageDigest.getInstance("MD5");
            messagedigest.update(buffer);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return bufferToHex(messagedigest.digest());
    }

    private String bufferToHex(byte bytes[]) {
        int len = bytes.length;
        StringBuffer stringbuffer = new StringBuffer(2 * len);
        int k = len;
        for (int l = 0; l < k; l++) {
            appendHexPair(bytes[l], stringbuffer);
        }
        return stringbuffer.toString();
    }

    private void appendHexPair(byte bt, StringBuffer stringbuffer) {
        char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
            'a', 'b', 'c', 'd', 'e', 'f' };
        char c0 = hexDigits[(bt & 0xf0) >> 4];// 取字节中高 4 位的数字转换
        // 为逻辑右移，将符号位一起右移,此处未发现两种符号有何不同
        char c1 = hexDigits[bt & 0xf];// 取字节中低 4 位的数字转换
        stringbuffer.append(c0);
        stringbuffer.append(c1);
    }

}
